package io.framework.modules.noise.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.framework.common.annotation.LogOperation;
import io.framework.common.exception.ErrorCode;
import io.framework.common.utils.ConvertUtils;
import io.framework.common.utils.Result;
import io.framework.common.validator.AssertUtils;
import io.framework.modules.noise.dto.NoiseFunctionalZoneDTO;
import io.framework.modules.noise.dto.NoiseMonitorDTO;
import io.framework.modules.noise.entity.NoiseFunctionalZoneEntity;
import io.framework.modules.noise.entity.NoiseMonitorEntity;
import io.framework.modules.noise.service.NoiseFunctionalZoneService;
import io.framework.modules.noise.service.NoiseMonitorService;
import io.framework.modules.noise.utils.NoiseFileCommonUtil;
import io.framework.modules.station.dto.StationDTO;
import io.framework.modules.station.service.StationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * /**
 * 〈噪声数据上传〉
 *
 * @Author GJQ
 * @Create 2020/6/1
 * @Since 1.0.0
 */
@RestController
@Api(tags = "噪声监测数据上传")
public class UploadNoiseDataController {

    private Logger logger = LoggerFactory.getLogger(UploadNoiseDataController.class);

    @Value("${file.upload.path}")
    private String FILE_UPLOAD_PATH;

    @Autowired
    private NoiseMonitorService noiseMonitorService;

    @Autowired
    private NoiseFunctionalZoneService noiseFunctionalZoneService;

    @Autowired
    private StationService stationService;

    @GetMapping("noise/upload/checkData")
    @ApiOperation("验证噪声数据上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "1-交通噪声 2-区域噪声 3-功能区噪声", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "year", value = "时间年份 例：2020", paramType = "query", dataType = "Integer", required = true),
    })
    public Result checkData(@RequestParam Map<String, Object> params) {

        logger.info("=======================验证噪声数据上传=======================");

        Integer type = Integer.parseInt(params.get("type").toString());
        String year = params.get("year").toString();
        Boolean flag;
        if (type == 3) {
            flag = noiseFunctionalZoneService.checkData(year);
        } else {
            flag = noiseMonitorService.checkData(year,type);
        }
        if (flag) {
            return new Result().error(ErrorCode.UPLOAD_FILE_CHECK);
        }
        return new Result();
    }

    @PostMapping("noise/upload/datas/uploadFile")
    @ApiOperation("噪声上传数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classify", value = "1-交通噪声 2-区域噪声 3-功能区噪声", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "year", value = "时间 年 例：2020", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "multipartFile", value = "文件", paramType = "query", dataType = "Integer", required = true),
    })
    @LogOperation("上传噪声站点监测数据")
    @RequiresPermissions("noise:info:upload")
    @SuppressWarnings("all")
    public Result readAir(Integer classify, String year, MultipartFile multipartFile) {
        AssertUtils.isBlank("classify", ErrorCode.NOT_NULL);
        AssertUtils.isBlank("year", ErrorCode.NOT_NULL);
        String filename = multipartFile.getOriginalFilename();
        if (StringUtils.isEmpty(filename)) {
            return new Result().error(ErrorCode.UPLOAD_FILE_EMPTY);
        }
        File file = new File(FILE_UPLOAD_PATH + DateUtil.format(new Date(), "yyyy-MM-dd"));
        if (!file.exists()) {
            file.mkdirs();
        }
        File excelFile = new File(file, File.separator + DateUtil.format(new Date(), "HHmmss") + filename.substring(filename.indexOf(".")));
        try {
            multipartFile.transferTo(excelFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath = excelFile.getPath();
        List<NoiseMonitorDTO> noiseList = new ArrayList<>();
        List<NoiseFunctionalZoneDTO> zoneList = new ArrayList<>();
        if (classify == 1 || classify == 2) {
            logger.info("=======================道路交通/区域噪声=======================");
            List<NoiseMonitorDTO> zhoujianList = NoiseFileCommonUtil.readNoiseData(1, classify, year, filePath);
            if (CollectionUtils.isNotEmpty(zhoujianList)) {
                noiseList.addAll(zhoujianList);
            }
            List<NoiseMonitorDTO> yejianList = NoiseFileCommonUtil.readNoiseData(2, classify, year, filePath);
            if (CollectionUtils.isNotEmpty(yejianList)) {
                noiseList.addAll(yejianList);
            }

        } else if (classify == 3) {
            logger.info("=======================功能区噪声=======================");
            zoneList = NoiseFileCommonUtil.readNoiseZoneData(filePath);
        } else {
            return new Result().error(ErrorCode.UPLOAD_FILE_TYPE_NOTNULL);
        }

        Map<String, Object> params = new HashMap<>(1);
        params.put("year", year);
        params.put("classify",classify);
        if (CollectionUtils.isNotEmpty(noiseList)) {
            logger.info("=======================添加 交通噪声/区域噪声 数据=======================");
            noiseList.forEach(v -> {
                Map<String, Object> map = new HashMap<>(2);
                map.put("name", v.getStationName());
                map.put("type", 4);
                List<StationDTO> stationDTOS = stationService.getStationInfoByParams(map);
                if (CollectionUtils.isNotEmpty(stationDTOS)) {
                    v.setStationId(stationDTOS.get(0).getId());
                }
            });
            logger.info("=======================清理历史数据=======================");
            noiseMonitorService.deleteInfoByDate(params);
            noiseMonitorService.insertBatch(ConvertUtils.sourceToTarget(noiseList, NoiseMonitorEntity.class));
        }

        if (CollectionUtils.isNotEmpty(zoneList)) {
            logger.info("=======================添加 功能区噪声 数据=======================");
            zoneList.forEach(v -> {
                Map<String, Object> map = new HashMap<>(2);
                map.put("name", v.getStationName());
                map.put("type", 4);
                List<StationDTO> stationDTOS = stationService.getStationInfoByParams(map);
                if (CollectionUtils.isNotEmpty(stationDTOS)) {
                    v.setStationId(stationDTOS.get(0).getId());
                }
            });
            List<String> yearList = NoiseFileCommonUtil.getYear(filePath);
            logger.info("=======================清理历史数据=======================");
            yearList.forEach(v -> {
                params.put("year", v);
                noiseFunctionalZoneService.deleteInfoByDate(params);
            });
            noiseFunctionalZoneService.insertBatch(ConvertUtils.sourceToTarget(zoneList, NoiseFunctionalZoneEntity.class));
        }
        return new Result().ok("上传成功");
    }
}
